package cgl.sensorgrid.sopac.gps.filters;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

import cgl.narada.event.NBEvent;
import cgl.sensorgrid.common.PropertyFile;
import cgl.sensorgrid.filters.Filter;

class StoreNetwork {
    public StoreNetwork() {
    }

    private Object syncObj1 = new Object();
    private List eventList = Collections.synchronizedList(new LinkedList());
    private String dataDir;
    private String templateDir;
    private java.util.Properties properties = new java.util.Properties();
    private int noOfObservations;
    private String NetworkName;
    static int runcount = 0;

    private Hashtable ht = new Hashtable();

    public StoreNetwork(String[] argsb) {
        loadProperties();
        dataDir = properties.getProperty("gps.data.directory");
        templateDir = properties.getProperty("gps.template.directory");
        System.out.println(
                "[SaveNetwork] --> Data Directory = " +
                dataDir);
        if (argsb.length == 2) {
            if (argsb[0] != null && argsb[0].length() > 0) {
                this.noOfObservations = Integer.parseInt(argsb[0]);
                this.NetworkName = argsb[1];
                this.dataDir = dataDir + "/" + NetworkName;
                System.out.println(
                        "[SaveNetwork] --> # Of Observations per file = " +
                        this.noOfObservations);
            }
        }
    }


    /**
     *
     * @return Properties
     */
    private java.util.Properties loadProperties() {
        // Read properties file.
        try {
            properties = PropertyFile.loadProperties(
                    "sensorgrid.properties");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return properties;
    }


    /**
     *
     * @param event NBEvent
     */
    public void addEvent(NBEvent event) {
        synchronized (syncObj1) {
            eventList.add(event);
            if (eventList.size() == 1) {
                syncObj1.notify();
            }
        }
    }


    /**
     *
     * @param event NBEvent
     */
    public void run() {
        boolean running = true;
        try {
            while (running) {
                synchronized (syncObj1) {
                    if (eventList.size() == 0) {
                        syncObj1.wait();
                    }
                    NBEvent nbEvent = (NBEvent) eventList.remove(0);
                    byte[] data2 = nbEvent.
                                   getContentPayload();
                    if (data2 != null && data2.length > 0) {
                        processMessage(new String(data2));
                    }
                }
            }
            return;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    static int eventcount = 0;

    public void processMessage(String msg) {
        try {
            StringTokenizer st = new StringTokenizer(msg, "\n");
            while (st.hasMoreTokens()) {
                String token = st.nextToken();
                if (!token.startsWith("EOF")) {
                    if (token.length() > 4) {
                        String station = token.substring(0, 4);
                        if (ht.get(station) != null) {
                            NetworkMessagesToFiles rd = (NetworkMessagesToFiles) ht.get(station);
                            rd.addLine(token + "\n");
                        } else {
                            NetworkMessagesToFiles rd = new NetworkMessagesToFiles(noOfObservations,
                                    dataDir, templateDir);
                            rd.setSiteName(station);
                            ht.put(station, rd);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}


/**
 *
 * <p>Title: SensorGrid</p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: </p>
 *
 * @author Galip Aydin
 * @version 1.0
 */
class NetworkMessagesToFiles {
    private String siteName;
    private StringBuffer data;
    private int lineCount;
    private int runcount;
    private int noOfObs;
    private int fwCount;

    private FileWriter fw;
    private String dataDir;
    private String templateDir;
    private String filePath;
    private String templateBatFile;
    private double xvalue;
    private double yvalue; 
    private double zvalue; 
    private int xzerocount;
    private int yzerocount;
    private int zzerocount;
    private String starttime;
    private String endtime;
    private String xcontent_plotfile;
    private String ycontent_plotfile;
    private String zcontent_plotfile;
    
    public NetworkMessagesToFiles(int noOfObservations, String dataDir_, String templateDir_) {
    	this.noOfObs = noOfObservations;
        fwCount = 0;
        siteName = "";
        lineCount = 0;
        data = new StringBuffer();
        dataDir = dataDir_;
        templateDir=templateDir_;
        runcount = 0;
        this.xcontent_plotfile = CreateNetworkPng.ReadFile(templateDir+"/"+"plot_x.plt");
        this.ycontent_plotfile = CreateNetworkPng.ReadFile(templateDir+"/"+"plot_y.plt");
        this.zcontent_plotfile = CreateNetworkPng.ReadFile(templateDir+"/"+"plot_z.plt");
        this.templateBatFile = CreateNetworkPng.ReadFile(templateDir+"/"+"plot_xyz.bat");
        xvalue=0;
        yvalue=0;
        zvalue=0;
        xzerocount=0;
        yzerocount=0;
        zzerocount=0;
        starttime="";
        endtime="";
    }

    public void setSiteName(String siteName_) {
        this.siteName = siteName_;
        System.out.println(
                "[NetworkMessagesToFiles] ---> Creating DataStruct for " +
                siteName);
        try {
            if (siteName != null && !siteName.equals("")) {
                File f = new File(dataDir + "/" + siteName);
                if(!f.exists()){
                    f.mkdirs();
                }

                this.filePath = dataDir + "/" + siteName + "/" + siteName + ".xyz";
 //plot x
                xcontent_plotfile=xcontent_plotfile.replace("{!outpng!}",dataDir + "/" + siteName + "/"+siteName+"_x.png");
                xcontent_plotfile=xcontent_plotfile.replace("{!datafile!}",dataDir + "/" + siteName + "/"+siteName+".xyz");
                String BatFileContent=new String(templateBatFile);
                BatFileContent=BatFileContent.replace("{!filename!}",dataDir + "/" + siteName + "/"+"plot_x.plt");
                CreateNetworkPng.WriteFile(dataDir + "/" + siteName + "/" + "plot_x.bat",BatFileContent,false);
//plot y
                ycontent_plotfile=ycontent_plotfile.replace("{!outpng!}",dataDir + "/" + siteName + "/"+siteName+"_y.png");
                ycontent_plotfile=ycontent_plotfile.replace("{!datafile!}",dataDir + "/" + siteName + "/"+siteName+".xyz");
                BatFileContent=templateBatFile;
                BatFileContent=BatFileContent.replace("{!filename!}",dataDir + "/" + siteName + "/"+"plot_y.plt");
                CreateNetworkPng.WriteFile(dataDir + "/" + siteName + "/" + "plot_y.bat",BatFileContent,false);
                
//plot z
                zcontent_plotfile=zcontent_plotfile.replace("{!outpng!}",dataDir + "/" + siteName + "/"+siteName+"_z.png");
                zcontent_plotfile=zcontent_plotfile.replace("{!datafile!}",dataDir + "/" + siteName + "/"+siteName+".xyz");
                BatFileContent=templateBatFile;
                BatFileContent=BatFileContent.replace("{!filename!}",dataDir + "/" + siteName + "/"+"plot_z.plt");
                CreateNetworkPng.WriteFile(dataDir + "/" + siteName + "/" + "plot_z.bat",BatFileContent,false);

    	        String osname = System.getProperty("os.name");
    	        if(osname.equals("Linux"))
    	        {
    	        	CreateNetworkPng.exec("chmod 777 "+ dataDir + "/" + siteName + "/"+ "*.bat");
    			// linux command
    	        } 
                
    	        starttime=cgl.sensorgrid.common.Tools.getDate(System.currentTimeMillis());
                fw = new FileWriter(filePath,false);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void setLineCount(int count) {
        this.setLineCount(count);
    }

    public void increaseLineCount() {
        this.lineCount++;
    }

    public void addLine(String line) {
        try {
            data.append(line);
            
            String tmps[] = line.split("\t");
            xvalue= xvalue + Float.valueOf(tmps[3]).floatValue() ;
            if( (int)Float.valueOf(tmps[3]).floatValue() == 0)
            {
            	xzerocount=xzerocount+1;
            }
            yvalue= yvalue + Float.valueOf(tmps[4]).floatValue() ;
            if( (int)Float.valueOf(tmps[4]).floatValue() == 0)
            {
            	yzerocount=yzerocount+1;
            }
            zvalue= zvalue + Float.valueOf(tmps[5]).floatValue() ;
            if( (int)Float.valueOf(tmps[5]).floatValue() == 0)
            {
            	zzerocount=zzerocount+1;
            }
            
            increaseLineCount();
            fwCount++;

            if (fwCount >= 90 || this.lineCount >= noOfObs) {
                fw.write(data.toString());
                fw.flush();

                fwCount = 0;
                data = new StringBuffer();
            }

            if (this.lineCount >= noOfObs) {
                fw.flush();
                fw.close();
                runcount++;

//x                
                String PlotFileContent=new String(xcontent_plotfile);
                PlotFileContent=PlotFileContent.replace("{!averge_value!}",String.valueOf( xvalue/(noOfObs-xzerocount) ) );
                CreateNetworkPng.WriteFile(dataDir + "/" + siteName + "/" + "plot_x.plt",PlotFileContent,false);
                System.out.println();
//y
                PlotFileContent=new String(ycontent_plotfile);
                PlotFileContent=PlotFileContent.replace("{!averge_value!}",String.valueOf( yvalue/(noOfObs-yzerocount) ) );
                CreateNetworkPng.WriteFile(dataDir + "/" + siteName + "/" + "plot_y.plt",PlotFileContent,false);
//z
                PlotFileContent=new String(zcontent_plotfile);
                PlotFileContent=PlotFileContent.replace("{!averge_value!}",String.valueOf( zvalue/(noOfObs-zzerocount) ) );
                CreateNetworkPng.WriteFile(dataDir + "/" + siteName + "/" + "plot_z.plt",PlotFileContent,false);
                
                endtime=cgl.sensorgrid.common.Tools.getDate(System.currentTimeMillis());
                CreateNetworkPng.exec(dataDir + "/" + siteName + "/"+ "plot_x.bat");
                CreateNetworkPng.exec(dataDir + "/" + siteName + "/"+ "plot_y.bat");
                CreateNetworkPng.exec(dataDir + "/" + siteName + "/"+ "plot_z.bat");
                String statcontent=xvalue/(noOfObs-xzerocount)+"\n"+yvalue/(noOfObs-yzerocount)+"\n"+zvalue/(noOfObs-zzerocount)+"\n"+starttime+"\n"+endtime;
                CreateNetworkPng.WriteFile(dataDir + "/" + siteName + "/" + "plot_stat.txt",statcontent,false);

                starttime=cgl.sensorgrid.common.Tools.getDate(System.currentTimeMillis());
                this.filePath = dataDir + "/" + siteName + "/" + siteName + ".xyz";

                fw = new FileWriter(filePath,false);
                this.lineCount = 0;
                this.data = new StringBuffer();
                xvalue=0;
                yvalue=0;
                zvalue=0;
                xzerocount=0;
                yzerocount=0;
                zzerocount=0;
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public String getSiteName() {
        return siteName;
    }

    public int getLineCount() {
        return this.lineCount;
    }

    public StringBuffer getData() {
        return this.data;
    }

}
/**
 *
 * <p>Title: SensorGrid</p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: </p>
 *
 * @author Galip Aydin
 * @version 1.0
 */
public class CreateNetworkPng extends Filter {
    public CreateNetworkPng() {
    }

    private StoreNetwork r2a;

	static Logger logger = Logger.getLogger(SimpleFilter.class.getName());


	/**
	 * Execute a command
	 * 
	 * @param execStr
	 *            String command string
	 * @return String the information of execute result
	 */
	public static String exec(String execStr) {
		Runtime runtime = Runtime.getRuntime();// Get current runtime object
		String outInfo = ""; // execute error information
		try {
	        String osname = System.getProperty("os.name");
	        String[] args = null;
	        if(osname.equals("Linux"))
	        {
			args = new String[] { "sh", "-c", execStr }; // execute
			// linux command
	        }
	        else if(osname.substring(0,3).equals("Win"))
	        {
			args = new String[] { "cmd", "/c", execStr }; // execute
	        }else
	        {
	        	System.exit(0);
	        }
			
//	        // String[] args = new String[] { "sh", "-c", execStr }; // execute
//			// linux command
//			String[] args = new String[] { "cmd", "/c", execStr }; // execute
//			// windows
//			// command
			
			Process proc = runtime.exec(args); // run another process to
			// execute command
			InputStream out = proc.getInputStream();
			BufferedReader br1 = new BufferedReader(new InputStreamReader(out));
			while (br1.readLine() != null) {
				// System.out.print(cc);
			}
			out.close();

			InputStream in = proc.getErrorStream(); // get error information
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String line = "";
			while ((line = br.readLine()) != null) {
				outInfo = outInfo + line + "/n";
				System.out.println(outInfo);
			}
			in.close();

			try { // check the result
				if (proc.waitFor() != 0) {
					System.err.println("exit value = " + proc.exitValue());
				}
			} catch (InterruptedException e) {
				System.err.print(e);
				e.printStackTrace();
			}

		} catch (IOException e) {
			System.out.println("exec error: " + e.getMessage());
			e.printStackTrace();
		}
		return outInfo;
	}
	public static void WriteFile(String Wfilename, String Wmessage, boolean Wtype) {
		try {
			BufferedWriter out = new BufferedWriter(new FileWriter(Wfilename,
					Wtype));
			out.write(Wmessage);
			out.close();
		} catch (IOException e) {
			logger.error("got an IOException error!");
			e.printStackTrace();
		}
	}
	public static String ReadFile(String Rfilename) {
		String Rmessage="";
		try {
			String record = null;
			BufferedReader out = new BufferedReader(new FileReader(Rfilename));
			record = new String();
			while ((record = out.readLine()) != null) 
			{
				Rmessage= Rmessage + record + "\n";
				record="";
		    }			
			out.close();
		} catch (IOException e) {
			logger.error("got an IOException error!");
			e.printStackTrace();
		}
		return Rmessage;
	}    
    
    public CreateNetworkPng(String[] args, String[] argsb) {
        if (args == null || args.length == 0) {
            System.err.println(
                    "Incorrect number of arguments in ryo2ascii::Constructor...");
        } else {
            this.initialize(args);
            r2a = new StoreNetwork(argsb);
            r2a.run();
        }
    }

    public void onEvent(NBEvent nbEvent) {
        if (nbEvent.getContentPayload() != null) {
            if (r2a != null && nbEvent != null) {
                r2a.addEvent(nbEvent);
            }
        }
    }

    public static void main(String args[]) {
        if (args.length < 6) {
            System.out.println("Usage: java cgl.sensorgrid.sopac.gps.filters.SaveNetwork commType nbHost nbPort subTopic noOfObservations NetworkName");
            System.exit(0);
        }

        String commType = args[0];
        String nbHost = args[1];
        String nbPort = args[2];
        String subTopic = args[3];
        String noOfObservations = args[4];
        String NetworkName = args[5];
       
//        String commType = "tcp";
//        String nbHost = "gf3.ucs.indiana.edu";
//        String nbPort = "5040";
//        String subTopic = "/SOPAC/GPS/CRTN_03/POS";
//        String noOfObservations = "600";
//        String NetworkName = "CRTN_03";

        String[] argsa = {commType,
                         nbHost,
                         nbPort,
                         subTopic,
                         ""};

        String[] argsb = { noOfObservations,NetworkName };
        CreateNetworkPng test = new CreateNetworkPng(argsa, argsb);
    }
}


